#include "oxford-word-updater.h"
#include "oxford-word-provider.h"
#include "network-error.h"
#include "parse-error.h"

using namespace Oxford;

WordUpdater::WordUpdater() : QObject(NULL)
{
    databaseManager = new Core::DatabaseManager("Oxford");
    _deepMode = false;
}

WordUpdater::~WordUpdater()
{
    delete databaseManager;
}

void Oxford::WordUpdater::setWordsList(const QStringList &words)
{
    _words = words;
}

void Oxford::WordUpdater::setDeepMode(bool deepMode)
{
    _deepMode = deepMode;
}

void WordUpdater::run()
{
    emit logMessage("Oxford words update started");
    emit updateStarted();

    try
    {
        foreach (const QString& word, _words)
        {
            if (_needToLoad(word))
            {
                QString rawWordData = oxfordLoader.loadWord(word);
                Word wordData = oxfordParser.parse(rawWordData);
                if (_goodWord(wordData))
                {
                    QString firstLetter = wordData.word().left(1);
                    QString twoLetters = wordData.word().left(2);
                    QString threeLetters = wordData.word().left(3);

                    if (firstLetter.length() == 1)
                        databaseManager->startSubStorage(firstLetter);
                    if (twoLetters.length() == 2)
                        databaseManager->startSubStorage(twoLetters);
                    if (threeLetters.length() == 3)
                        databaseManager->startSubStorage(threeLetters);

                    databaseManager->store(word, wordData.toString());

                    if (threeLetters.length() == 3)
                        databaseManager->finishSubStorage();
                    if (twoLetters.length() == 2)
                        databaseManager->finishSubStorage();
                    if (firstLetter.length() == 1)
                        databaseManager->finishSubStorage();
                }
            }
        }
    }
    catch(Core::ENetworkError e)
    {
        emit logError(e.fullMessage());
    }
    catch (Core::EParseError e)
    {
        emit logError(e.fullMessage());
    }
    catch(...)
    {
        emit logError("Unknown update error");
    }

    emit updateFinished();
    emit logMessage("Oxford words update finished");
}

bool Oxford::WordUpdater::_needToLoad(const QString &word)
{
    return (_deepMode) || (WordProvider().wordExists(word));
}

bool Oxford::WordUpdater::_goodWord(const Oxford::Word &wordData)
{
    return !wordData.word().isEmpty() && !wordData.variants().isEmpty();
}
